---
title: Federation
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

`nestjs-query` provides **basic** federation support, with the intention of helping to
 * Plug into existing federated graphs, through references.
 * Create a federated relations/connections on types defined in other services.

These docs assume you have read
* https://docs.nestjs.com/graphql/federation
* https://www.apollographql.com/docs/apollo-server/federation/introduction/

## Base Type

The simplest way to integrate with a federated graph is through references.

A reference is an object that looks like

```ts
{ __typename: 'TodoItem', id: subTask.todoItemId }
```

The `__typename` lets the gateway know which type is being referenced with additional fields that can be used to uniquely identify the type.

:::note
Both of the examples below add a `resolveReference` function see https://www.apollographql.com/docs/apollo-server/federation/entities/#resolving
:::

To reference a type in `nestjs-query` you must first create DTO that defines the base type.

### Base Type
The base type in its own service must be decorated with federated directives specifying its key.

```ts title="todo-item/todo-item.dto.ts"
import { FilterableField } from '@nestjs-query/query-graphql';
import { ObjectType, ID, GraphQLISODateTime, Directive } from '@nestjs/graphql';

@ObjectType('TodoItem')
@Directive('@key(fields: "id")')
export class TodoItemDTO {
  @FilterableField(() => ID)
  id!: number;
  ...
}
```

### Auto Generated Resolver
When using the `NestjsQueryGraphQLModule` module add the `referenceBy` option that `nestjs-query` will use to automatically expose add a `@ResolveReference` decorator and method that the gateway can use.

```ts title="todo-item/todo-item.module.ts" {14-15}
import { NestjsQueryGraphQLModule } from '@nestjs-query/query-graphql';
import { Module } from '@nestjs/common';
import { TodoItemDTO } from './todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';

@Module({
  imports: [
    NestjsQueryGraphQLModule.forFeature({
      imports: [ /* import the nestjs-query persistence module*/],
      resolvers: [
        {
          DTOClass: TodoItemDTO,
          EntityClass: TodoItemEntity,
          // specify the referenceBy option letting nestjs-query know to to resolve a reference
          referenceBy: { key: 'id' },
        },
      ],
    }),
  ],
})
export class TodoItemModule {}

```

:::note
The `referenceBy.key` should be the field you want to look up the DTO by.
:::

### Manual Resolver

If you want to manually define your resolver pass in the `referenceBy` option to the `CRUDResolver`.


```ts title="todo-item.resolver.ts" {3-4}
@Resolver(() => TodoItemDTO)
export class TodoItemResolver extends CRUDResolver(TodoItemDTO, {
  // specify the referenceBy option letting nestjs-query know to to resolve a reference
  referenceBy: { key: 'id' },
}) {
  constructor(@InjectQueryService(TodoItemEntity) readonly service: QueryService<TodoItemEntity>) {
    super(service);
  }
}
```

:::note
The `referenceBy.key` should be the field you want to look up the DTO by.
:::

### App Module

This app module **must** also use the `GraphQLFederationModule` in order for the base type to be resolved by the gateway.

```ts title="app.module.ts"
import { GraphQLFederationModule } from '@nestjs/graphql';

@Module({
  imports: [
    TypeOrmModule.forRoot(ormconfig as TypeOrmModuleOptions),
    GraphQLFederationModule.forRoot({
      autoSchemaFile: 'schema.gql',
    }),
    TodoItemModule,
  ],
})
export class AppModule {}
```

## Reference Base Type
In a separate service from the one defining the base type above, we can use Apollo Federation to extend that base type.

To do this with `nestjs-query` you must create a type that extends the base type contained in some other graphql service.

:::warning
The type name must be the same name as the type it extends in the graph.
:::


For example

```ts title="sub-task/todo-item-reference.dto.ts" {4-5}
import { ObjectType, Directive, Field, ID } from '@nestjs/graphql';

@ObjectType('TodoItem')
@Directive('@extends')
@Directive('@key(fields: "id")')
export class TodoItemReferenceDTO {
  @Field(() => ID)
  @Directive('@external')
  id!: number;
}

```
:::note
Notice how the `@Directive` decorator is used to add the `@extends` annotation along with the `@keys`.

To read more about `@extends` annotation see https://www.apollographql.com/docs/apollo-server/federation/entities/#extending
:::

### @Reference Decorator

To reference a type defined in another service you can use the `@Reference` decorator.

When using the `@Reference` decorator `nestjs-query` will **NOT** look up the relation through the `QueryService`, instead return a reference type like the one described above.

```ts title="sub-task/sub-task.dto.ts" {5-6}
import { FilterableField, Reference } from '@nestjs-query/query-graphql';
import { ObjectType, ID, GraphQLISODateTime } from '@nestjs/graphql';

@ObjectType('SubTask')
// add a todoItem reference and use the subTask.todoItemId as the id
@Reference('todoItem', () => TodoItemReferenceDTO, { id: 'todoItemId' })
export class SubTaskDTO {
  @FilterableField(() => ID)
  id!: number;

  @FilterableField()
  title!: string;

  @FilterableField({ nullable: true })
  description?: string;

  @FilterableField()
  completed!: boolean;

  @FilterableField(() => GraphQLISODateTime)
  created!: Date;

  @FilterableField(() => GraphQLISODateTime)
  updated!: Date;

  @FilterableField()
  todoItemId!: string;
}
```

In the above example we provided the keys which look like the following

```ts
{ id: 'todoItemId' }
```

Which will map the `SubTask.todoItemId` to the `id` field in the reference type.

Assuming you have the following `SubTask`

```ts
{id: 1, title: 'Sub Task 1', completed: false, todoItemId: 2}
```

The reference type would be
```ts
{ __typename: 'TodoItem', id: 2 }
```

### Resolver

Now that we have added the decorator the `nestjs-query` resolver will automatically add the reference to the graphql type when using `NestjsQueryGraphQLModule` or `CRUDResolver`

<Tabs
  defaultValue="module"
  values={[
    { label: 'NestjsQueryGraphQLModule', value: 'module', },
    { label: 'CRUDResolver', value: 'resolver', },
  ]
}>
<TabItem value="module">

```ts title="sub-task/sub-task.module.ts"
import { NestjsQueryGraphQLModule } from '@nestjs-query/query-graphql';
import { Module } from '@nestjs/common';
import { SubTaskDTO } from './dto/sub-task.dto';
import { SubTaskEntity } from './sub-task.entity';

@Module({
  imports: [
    NestjsQueryGraphQLModule.forFeature({
      imports: [ /* import the nestjs-query persistence module*/],
      resolvers: [{ DTOClass: SubTaskDTO, EntityClass: SubTaskEntity }],
    }),
  ],
})
export class SubTaskModule {}
```


</TabItem>
<TabItem value="resolver">


```ts title="sub-task/sub-task.resolver.ts"
import { QueryService, InjectQueryService } from '@nestjs-query/core';
import { CRUDResolver } from '@nestjs-query/query-graphql';
import { Resolver } from '@nestjs/graphql';
import { SubTaskDTO } from './sub-task.dto';
import { TodoItemReferenceDTO } from './dto/todo-item-reference.dto';
import { SubTaskEntity } from './sub-task.entity';

@Resolver(() => SubTaskDTO)
export class SubTaskResolver extends CRUDResolver(SubTaskDTO) {
  constructor(@InjectQueryService(SubTaskEntity) readonly service: QueryService<SubTaskEntity>) {
    super(service);
  }
}
```

</TabItem>
</Tabs>

## Federated Relations

Another common use case is to add `relations` to a federated type from another service.

Lets continue with the `SubTask` example used above. We have add a `todoItem` reference to the `SubTask` but now lets add subTasks to the `TodoItem`.

### RelationQueryService

The first step is to create a `RelationQueryService`. The `RelationQueryService` is a special type of `QueryService` that allows looking up relations without defining them in your entity.

```ts title="todo-item.service.ts"
import { InjectQueryService, QueryService, RelationQueryService } from '@nestjs-query/core';
import { TodoItemReferenceDTO } from './todo-item-reference.dto';
import { SubTaskEntity } from './sub-task.entity';

@QueryService(TodoItemReferenceDTO)
export class TodoItemService extends RelationQueryService<TodoItemReferenceDTO> {
  constructor(@InjectQueryService(SubTaskEntity) readonly subTaskService: QueryService<SubTaskEntity>) {
    super({
      // the name of the relation
      subTasks: {
        service: subTaskService,
        // a query factory that will take in the reference to create a query.
        query: (todoItemReferenceDTO) => ({ filter: { todoItemId: { eq: todoItemReferenceDTO.id } } }),
      },
    });
  }
}

```

In this example we inject a `SubTask` service that will be used to look up `subTask` relations. The `query` method is used to filter relations when `findRelation` or `queryRelations` is called.

```ts
{
  // the name of the relation
  subTasks: {
    // the service to delegate to when looking up the relations
    service: subTaskService,
    // a query factory that will take in the reference to create a query.
    query: (todoItemReferenceDTO) => ({ filter: { todoItemId: { eq: todoItemReferenceDTO.id } } }),
  },
}
```

### Add the Connection

Next we add the `subTasks` connection to the `TodoItemReferenceDTO`.

:::note
The name of the relation should match the name of the relation defined by your `RelationQueryService`.
:::

:::note
The same pattern applies when you have a single relation and use the `@Relation` decorator.
:::

```ts title='sub-task/todo-item-reference.dto.ts'
import { Connection } from '@nestjs-query/query-graphql';
import { ObjectType, Directive, Field, ID } from '@nestjs/graphql';
import { SubTaskDTO } from './sub-task.dto';

@ObjectType('TodoItem')
@Directive('@extends')
@Directive('@key(fields: "id")')
@CursorConnection('subTasks', () => SubTaskDTO)
export class TodoItemReferenceDTO {
  @Field(() => ID)
  @Directive('@external')
  id!: number;
}

```

### Federation Resolver

Next we set up our resolver that exposes the relations in the schema. As with other resolvers you can use the `NestjsQueryGraphQLModule` or define your own `FederationResolver`.

<Tabs
  defaultValue="module"
  values={[
    { label: 'NestjsQueryGraphQLModule', value: 'module', },
    { label: 'FederationResolver', value: 'resolver', },
  ]
}>
<TabItem value="module">

When using the `NestjsQueryGraphQLModule` set the `type` of the resolver to `federated`, and specify the `Service`.

Also, add the `TodoItemService` to the `services` option to make it available for nest to inject the service into the auto-generated resolver.

```ts title="sub-task/sub-task.module.ts" {12,18-22}
import { NestjsQueryGraphQLModule } from '@nestjs-query/query-graphql';
import { Module } from '@nestjs/common';
import { SubTaskDTO } from './dto/sub-task.dto';
import { SubTaskEntity } from './sub-task.entity';
import { TodoItemReferenceDTO } from './dto/todo-item-reference.dto';
import { TodoItemService } from './todo-item.service';

@Module({
  imports: [
    NestjsQueryGraphQLModule.forFeature({
      imports: [/* import the nestjs-query persistence module*/],
      services: [TodoItemService],
      resolvers: [
        {
          DTOClass: SubTaskDTO,
          EntityClass: SubTaskEntity,
        },
        {
          type: 'federated',
          DTOClass: TodoItemReferenceDTO,
          Service: TodoItemService,
        },
      ],
    }),
  ],
})
export class SubTaskModule {}

```

</TabItem>
<TabItem value="resolver">

When manually defining the resolver extend the `FederationResolver`.

The `FederationResolver` this will not set up any queries or mutations in the graph. Instead, it is used set up the reading of relations for a type that originates from another service.


```ts title="sub-task/todo-item.resolver.ts"
import { FederationResolver } from '@nestjs-query/query-graphql';
import { Resolver } from '@nestjs/graphql';
import { TodoItemReferenceDTO } from './todo-item-reference.dto';
import { TodoItemService } from './todo-item.service';

@Resolver(() => TodoItemReferenceDTO)
export class TodoItemResolver extends FederationResolver(TodoItemReferenceDTO) {
  constructor(readonly service: TodoItemService) {
    super(service);
  }
}
```

</TabItem>
</Tabs>

## Complete Example

To see a complete example checkout https://github.com/doug-martin/nestjs-query/tree/master/examples/federation



